import 'dart:async';
import 'package:ble_helper_plugin/library.dart';
import 'package:flutter/foundation.dart';
import '../../library.dart';
import 'encrypt_decryt_helper.dart';

// 消息发送助手基类
abstract class MessageSendHelper {
  // 加密/解密助手
  EncryptDecryptHelper get encryptDecryptHelper;

  // 蓝牙发送处理
  BluetoothSendHelper get bleSendHelper;

  // 当前消息发送方式
  bool isBluetoothSendMethod = true;

  // 消息发送回调（用于http发送消息后，再次回调进来处理后续流程）
  DataProcessor? onMessageHttpSent;

  // 发送请求 支持设置重试次数
  Future<Uint8List> sendRequest(
    Uint8List msg, {
    Duration? timeout = const Duration(milliseconds: 1500), // 默认超时时间
    int maxRetries = 3, // 默认最大重试次数
    Duration retryDelay = const Duration(milliseconds: 500), // 默认重试延迟
  }) async {
    int attempt = 0;
    String errMsg = '';
    while (attempt < maxRetries) {
      try {
        // 发送请求并获取响应
        Uint8List response = await _request(msg, timeout: timeout);
        return response; // 如果成功，直接返回结果
      } catch (e) {
        if (e is TimeoutException) {
          attempt++;
          if (attempt >= maxRetries) {
            // 超过最大重试次数，抛出异常
            throw TimeoutException(e.message, timeout);
          }
          // 等待一段时间后重试
          await Future.delayed(retryDelay);
          debugPrint('🟨 ${msg.toString()}($e),重试第 $attempt 次');
        } else {
          errMsg = e.toString();
          break; // 如果不是超时异常，直接退出循环
        }
      }
    }
    throw Exception(errMsg);
  }

  // 发送请求 & 接收响应
  Future<Uint8List> _request(
    Uint8List msg, {
    Duration? timeout,
  }) async {
    if (isBluetoothSendMethod) {
      List<int> rsp = await bleSendHelper.sendRequest(
        encryptDecryptHelper.encrypt(msg),
        timeout: timeout,
      );
      return encryptDecryptHelper.decrypt(Uint8List.fromList(rsp));
    } else {
      if (onMessageHttpSent != null) {
        Uint8List requestData = encryptDecryptHelper.encrypt(msg);
        Uint8List rsp = await onMessageHttpSent!(requestData);
        return encryptDecryptHelper.decrypt(Uint8List.fromList(rsp));
      }
      throw Exception('未设置HTTP发送消息回调 - onMessageHttpSent');
    }
  }

  // 蓝牙主动响应数据监听（该数据为原始数据，经过一层解密，如果想合理的使用蓝牙响应数据，请从协议层调用）
  Stream<List<int>>? get responseNotifyStream =>
      bleSendHelper.notifyStream?.map((data) =>
          encryptDecryptHelper.decrypt(Uint8List.fromList(data)).toList());
}
